package exp4;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.Scanner;

class Head {
    int nPosition;
    boolean bVisited;
    public Head(){
    }
    public Head(int x, boolean flg){
        this.nPosition = x;
        this.bVisited = flg;
    }
}

public class DiskScheduling {

    public static void visit(Head pHead) {
        System.out.println("访问磁道: " + pHead.nPosition);
        pHead.bVisited = true;
    }

    public static int readInputKeyboard(Head[] pHead, int[] pCurrentPosition, int nMaxNumber) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入当前位置: ");
        pCurrentPosition[0] = scanner.nextInt();
        System.out.print("请输入要访问的位置: ");
        for (int i = 0; i < nMaxNumber; i++) {
            pHead[i].nPosition = scanner.nextInt();
            pHead[i].bVisited = false;
            if (pHead[i].nPosition < 0)
                break;
        }
        return scanner.nextInt();
    }

    public static int readInputFile(Head[] pHead, int[] pCurrentPosition, int nMaxNumber) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入文件名: ");
        String szFileName = scanner.next();
        int i = 0;
        try (BufferedReader br = new BufferedReader(new FileReader(szFileName))) {
            String line;
            while ((line = br.readLine()) != null && i < nMaxNumber) {
                String[] parts = line.split(",");
                pCurrentPosition[0] = Integer.parseInt(parts[0]);
                for (int j = 1; j < parts.length; j++) {
                    pHead[i].nPosition = Integer.parseInt(parts[j]);
                    pHead[i].bVisited = false;
                    i++;
                }
            }
        } catch (IOException e) {
            System.out.println("打开文件 " + szFileName + " 出错");
            return -1;
        }
        return i;
    }

    /**
     * 先来先服务
     */
    public static int fifoVisit(int nCurrentPosition, Head[] pHead, int nNumber) {
        int nHaveVisited = 0;
        int nMoveDistance = 0;
        while (nHaveVisited < nNumber) {
            for (int i = 0; i < nNumber; i++) {
                if (pHead[i].bVisited)
                    continue;
                visit(pHead[i]);
                nHaveVisited++;
                nMoveDistance += Math.abs(nCurrentPosition - pHead[i].nPosition);
                nCurrentPosition = pHead[i].nPosition;
            }
        }
        System.out.println("移动距离总和: " + nMoveDistance);
        return nMoveDistance;
    }

    /**
     * 最短距离优先
     */
    public static int ssfoVisit(int nCurrentPosition, Head[] pHead, int nNumber) {
        int nMoveDistance = 0;
        int cnt = 0;
        while (cnt < nNumber) {
            int nMinDistance = Integer.MAX_VALUE;
            int nMinIndex = 0;
            for (int i = 0; i < nNumber; i++) {
                if (pHead[i].bVisited)
                    continue;
                if (nMinDistance > Math.abs(pHead[i].nPosition - nCurrentPosition)) {
                    nMinDistance = Math.abs(pHead[i].nPosition - nCurrentPosition);
                    nMinIndex = i;
                }
            }
            visit(pHead[nMinIndex]);
            nMoveDistance += nMinDistance;
            cnt++;
            nCurrentPosition = pHead[nMinIndex].nPosition;
        }
        System.out.println("移动距离总和: " + nMoveDistance);
        return nMoveDistance;
    }

    /**
     * 电梯调度算法
     */
    public static int dtVisit(int nCurrentPosition, boolean bOut, Head[] pHead, int nNumber) {
        int nHaveVisited = 0;
        int nMoveDistance = 0;
        while (nHaveVisited < nNumber) {
            int nMinDistance = Integer.MAX_VALUE;
            int nMinIndex = 0;
            for (int i = 0; i < nNumber; i++) {
                if (pHead[i].bVisited)
                    continue;
                if ((bOut && pHead[i].nPosition < nCurrentPosition) || (!bOut && pHead[i].nPosition > nCurrentPosition)) {
                    if (nMinDistance > Math.abs(pHead[i].nPosition - nCurrentPosition)) {
                        nMinDistance = Math.abs(pHead[i].nPosition - nCurrentPosition);
                        nMinIndex = i;
                    }
                }
            }
            if (nMinDistance == Integer.MAX_VALUE) {
                bOut = !bOut;
                continue;
            }
            visit(pHead[nMinIndex]);
            nHaveVisited++;
            nMoveDistance += nMinDistance;
            nCurrentPosition = pHead[nMinIndex].nPosition;
        }
        System.out.println("移动距离总和："+nMoveDistance);
        return nMoveDistance;
    }

    /**
     * 单项调度算法
     */
    public static int dxVisit(int nCurrentPosition, Head[] pHead, int nNumber) {
        int nHaveVisited = 0;
        int nMoveDistance = 0;
        while (nHaveVisited < nNumber) {
            int nMinDistance = Integer.MAX_VALUE;
            int nMinIndex = 0;
            for (int i = 0; i < nNumber; i++) {
                if (pHead[i].bVisited)
                    continue;
                if (nMinDistance > Math.abs(pHead[i].nPosition - nCurrentPosition)) {
                    nMinDistance = Math.abs(pHead[i].nPosition - nCurrentPosition);
                    nMinIndex = i;
                }
            }
            if (nMinDistance == Integer.MAX_VALUE) {
                nMoveDistance += 199 - nCurrentPosition;//当前方向没有点，要回到原点
                nCurrentPosition = 0;
                continue;
            }
            visit(pHead[nMinIndex]);
            nHaveVisited++;
            nMoveDistance += nMinDistance;
            nCurrentPosition = pHead[nMinIndex].nPosition;
        }
        System.out.println("移动距离总和: " + nMoveDistance);
        return nMoveDistance;
    }

    public static void main(String[] args) {
        Head[] mylist = new Head[20];
        int[] arr = new int[]{98, 183, 37, 122, 14, 124, 65, 67};
        int start = 53;
        int size = arr.length;
        for (int i = 0; i < size; i++) {
            mylist[i] = new Head();
            mylist[i].nPosition = arr[i];
            mylist[i].bVisited = false;
        }
        //fifoVisit(start, mylist, size);
        //ssfoVisit(start, mylist, size);
        //dtVisit(start, true, mylist, size);
        dxVisit(start, mylist, size);
        //int[] nCurrentPosition = new int[1];
        //int nRealNumber = readInputFile(mylist, nCurrentPosition, 20);
        //dxVisit(nCurrentPosition[0], mylist, nRealNumber);
    }
}